package com.ruoyi.function.service.impl;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;

import com.ruoyi.function.constant.BusinessConstants;
import com.ruoyi.function.domain.Garage;
import com.ruoyi.function.domain.OrderItems;
import com.ruoyi.function.domain.Orders;
import com.ruoyi.function.domain.Technician;
import com.ruoyi.function.domain.bo.OrdersBo;
import com.ruoyi.function.domain.vo.OrdersVo;
import com.ruoyi.function.mapper.GarageMapper;
import com.ruoyi.function.mapper.OrderItemsMapper;
import com.ruoyi.function.mapper.OrdersMapper;
import com.ruoyi.function.mapper.TechnicianMapper;
import com.ruoyi.function.service.IOrdersService;
import com.ruoyi.function.service.ISysTopUpService;
import com.ruoyi.function.service.ITransferResultService;
import com.ruoyi.function.service.IUserFlowingService;

import com.ruoyi.message.controller.NoticeController;
import com.ruoyi.message.notice.vo.NoticeVO;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.ruoyi.common.utils.PageUtils.startPage;

/**
 * 订单Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-20
 */
@Service
public class OrdersServiceImpl implements IOrdersService {
    private static final Logger log = LoggerFactory.getLogger(OrdersServiceImpl.class);
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private OrderItemsMapper orderItemsMapper;
    @Autowired
    private ISysTopUpService sysTopUpService;
    @Autowired
    private TechnicianMapper technicianMapper;
    @Autowired
    private GarageMapper garageMapper;
    @Autowired
    private IUserFlowingService userFlowingService;
    @Autowired
    private SysDictDataMapper dictDataMapper;
    @Autowired
    private ITransferResultService transferResultService;
    @Autowired
    private NoticeController noticeController;


    @Autowired
    private SysConfigMapper configMapper;
    @Autowired
    private SysTopUpServiceImpl topUpService;


    /**
     * 查询订单
     *
     * @param orderId 订单主键
     * @return 订单
     */
    @Override
    public OrdersVo selectOrdersByOrderId(Long orderId) {
        Orders orders = ordersMapper.selectOrdersByOrderId(orderId);
        OrdersVo ordersVo=  ordersToOrdersVo(orders);
        List<Orders> list = ordersMapper.selectOrdersByParentOrderType(orders.getOrderId());
        List<OrdersVo> list1 = new ArrayList<>();
        for (Orders orders1 : list) {
            list1.add(ordersToOrdersVo(orders1)) ;
        }
        ordersVo.setOrdersVoList(list1);
        return ordersVo;
    }

    private OrdersVo ordersToOrdersVo(Orders orders) {
        OrdersVo ordersVo = new OrdersVo();
        BeanUtils.copyProperties(orders, ordersVo);
        if (StringUtils.isNotEmpty(ordersVo.getPhotos())) {
            ordersVo.setPhotosArray(ordersVo.getPhotos().split(","));
        }
        if ("2".equals(orders.getReceivingType())) {
            Technician technician = technicianMapper.selectByUserId(orders.getOrdersUser());
            if (technician != null) {
                ordersVo.setMerchantPhone(technician.getPhone());
                ordersVo.setMerchantName(technician.getName());
                ordersVo.setMerchantAvatar(technician.getAvatar());
            }

        } else if ("3".equals(orders.getReceivingType())) {
            Garage garage = garageMapper.selectByUserId(orders.getOrdersUser());
            if (garage != null) {
                ordersVo.setMerchantPhone(garage.getContactMobile());
                ordersVo.setMerchantName(garage.getGarageName());
                ordersVo.setGarageAddress(garage.getAddressName());
                ordersVo.setMerchantAvatar(garage.getAvatar());
            }

        }

        //商家名称电话
//        SysUser user1 = userMapper.selectUserById(orders.getOrdersUser());
//        if (user1 != null){
//            ordersVo.setMerchantName(user1.getNickName());
//        }
        // 客户名称电话
        SysUser user = userMapper.selectUserById(orders.getUserId());
        if (user != null){
            ordersVo.setClientName(user.getNickName());
            ordersVo.setClientPhone(user.getPhonenumber());
            ordersVo.setClientAvatar(user.getAvatar());
        }
        List<OrderItems> orderItemsList = orderItemsMapper.selectByOrderId(orders.getOrderId());
        ordersVo.setOrderItemsList(orderItemsList);
        return ordersVo;
    }

    /**
     * 查询订单列表
     *
     * @param orders 订单
     * @return 订单
     */
    @Override
    public List<Orders> selectOrdersList(Orders orders) {
        return ordersMapper.selectOrdersList(orders);
    }


    @Override
    public List<OrdersVo> selectOrdersVoList(Orders orders) {

        List<Orders> list = ordersMapper.selectOrdersList(orders);

        List<OrdersVo> ordersVoList = new ArrayList<>();
        for (Orders orders1 : list) {

            OrdersVo ordersVo1 = ordersToOrdersVo(orders1);
            ordersVoList.add(ordersVo1);
        }
        return ordersVoList;
    }

    @Override
    public int paymentSuccess(Orders orders) {
        Orders orders1 = ordersMapper.selectOrdersByOrderId(orders.getOrderId());
        log .info("订单支付成功，订单号：{}", orders.getOrderId());
        if (orders1 == null || !orders1.getOrderStatus().equals("0")) {
            return 1;
        }
        Orders orders2 = new Orders();
        orders2.setOrderId(orders.getOrderId());
        orders2.setOrderStatus(BusinessConstants.dict.order_status_1);
        return ordersMapper.updateOrders(orders2);
    }

    @Override
    @Transactional
    public int updateOrderStatus(Orders orders) {




        Orders orders1 = ordersMapper.selectOrdersByOrderId(orders.getOrderId());

        if (orders.getOrderStatus().equals("1")) {
            //只有待付款才能改成待接单
            if (!orders1.getOrderStatus().equals("0")) {
                throw new RuntimeException("只有待付款才能改成待接单");
            }
            //发送消息
            NoticeVO noticeVO = new NoticeVO();
            noticeVO.setReceiverId(orders1.getOrdersUser() + "");
            noticeVO.setMessageContent(BusinessConstants.message_1);
            noticeVO.setUserType(orders1.getReceivingType());
            noticeController.add(noticeVO);
        }
        if (orders.getOrderStatus().equals("5")) {

            //1:订单已完成 。修改用户余额
            if (orders1.getOrdersUser() != null) {
                //修改用户余额
                userFlowingService.addAmount(orders1.getOrdersUser(), orders1.getTotalAmount(), BusinessConstants.dict.fee_type_1, orders1.getReceivingType(), orders1.getUserId());
                if (orders1.getReceivingType().equals("2")) {
                    Technician technician = technicianMapper.selectByUserId(orders1.getOrdersUser());
                    if (technician != null) {
                        technician.setCompleteOrderCount(technician.getCompleteOrderCount() + 1);
                        technician.setWorkingHours( addWorkingHours(technician.getWorkingHours(),orders1.getWorkingHours()));
                        technicianMapper.updateTechnician(technician);
                    }
                } else if (orders1.getReceivingType().equals("3")) {
                    Garage garage = garageMapper.selectByUserId(orders1.getOrdersUser());
                    if (garage != null) {
                        garage.setCompleteOrderCount(garage.getCompleteOrderCount() + 1);
                        garage.setWorkingHours( addWorkingHours(garage.getWorkingHours(),orders1.getWorkingHours()) );
                        garageMapper.updateGarage(garage);
                    }

                }

            }
        } else if (orders.getOrderStatus().equals("3")) {

            Date date = DateUtils.parseDate(orders.getAppointmentTime());

            Date date1 = DateUtils.addHours(date, orders.getWorkingHours());
            //技师或客户接单
            if (orders1.getReceivingType().equals("2")) {
                Technician technician = technicianMapper.selectByUserId(orders1.getOrdersUser());
                if (technician != null) {

                    technician.setAppointmentTime(date1);
                    technicianMapper.updateTechnician(technician);
                }
            } else if (orders1.getReceivingType().equals("3")) {
                Garage garage = garageMapper.selectByUserId(orders1.getUserId());
                if (garage != null) {
                    garage.setAppointmentTime(date1);
                    garageMapper.updateGarage(garage);
                }

            }
        }
        else if (orders.getOrderStatus().equals("4")) {
            //客户取消订单退款
            if (!orders1.getOrderStatus().equals("1")) {
                throw new RuntimeException("只有待接单才能退款");
            }
            //发送消息
            NoticeVO noticeVO = new NoticeVO();
            noticeVO.setReceiverId(orders1.getUserId() + "");
            noticeVO.setMessageContent(BusinessConstants.message_3);
            noticeVO.setUserType(orders1.getReceivingType());
            noticeController.add(noticeVO);
        }
        int i = ordersMapper.updateOrders(orders);
        //同步修改子订单的数据
        if (i<=0){
            throw new RuntimeException("订单状态修改失败");
        }
        ordersMapper.updateOrderStatusByParentOrder(orders.getOrderId(),orders.getOrderStatus());
        return i;
    }




        public BigDecimal  addWorkingHours(BigDecimal technician, BigDecimal order) {
            BigDecimal techHours = Optional.ofNullable(technician)
                    .orElse(BigDecimal.ZERO);
            BigDecimal orderHours = Optional.ofNullable(order)
                    .orElse(BigDecimal.ZERO);
            return techHours.add(orderHours);
        }

    @Override
    public int evaluation(Orders orders) {
        Orders orders1 = ordersMapper.selectOrdersByOrderId(orders.getOrderId());
        if (!orders1.getOrderStatus().equals("5")) {
            throw new RuntimeException("只有订单完成才能评价");
        }
        if (orders1.getReceivingType().equals("2")) {
            Technician technician = technicianMapper.selectByUserId(orders1.getOrdersUser());
            if (technician != null) {
                if (orders.getRatings() != null) {
                    Technician technician1 = new Technician();
                    technician1.setId(technician.getId());
                    technician1.setScoreCount(technician.getScoreCount() + 1);
                    technician1.setTotalScore(technician.getTotalScore().add(new BigDecimal(orders.getRatings())));
                    technician1.setAvgScore(technician1.getTotalScore().divide(new BigDecimal(technician1.getScoreCount()), 1, RoundingMode.HALF_UP));
                    technicianMapper.updateTechnician(technician1);
                }
            }
        } else if (orders1.getReceivingType().equals("3")) {
            Garage garage = garageMapper.selectByUserId(orders1.getOrdersUser());
            if (garage != null) {
                if (orders.getRatings() != null) {
                    Garage garage1 = new Garage();
                    garage1.setId(garage.getId());
                    garage1.setScoreCount(garage.getScoreCount() + 1);
                    garage1.setTotalScore(garage.getTotalScore().add(new BigDecimal(orders.getRatings())));
                    garage1.setAvgScore(garage1.getTotalScore().divide(new BigDecimal(garage1.getScoreCount()), 1, RoundingMode.HALF_UP));
                garageMapper.updateGarage(garage1);
            }
            }
        }
        Orders orders2 = new Orders();
        orders2.setOrderId(orders.getOrderId());
        orders2.setEvaluation(orders.getEvaluation());
        orders2.setRatings(orders.getRatings());
        orders2.setOrderStatus(BusinessConstants.dict.order_status_7);
        return ordersMapper.updateOrders(orders2);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancelOrder(Orders orders) {
        Long orderId = orders.getOrderId();
        if (orderId == null) {
            throw new IllegalArgumentException("订单ID不能为空");
        }

        // 查询当前订单信息
        Orders currentOrder = ordersMapper.selectOrdersByOrderId(orderId);
        if (currentOrder == null) {
            throw new RuntimeException("未找到订单: " + orderId);
        }

        // 确定目标父订单ID
        Long targetParentOrderId = currentOrder.getParentOrder() != null
                ? currentOrder.getParentOrder()  // 如果是子订单，取父ID
                : currentOrder.getOrderId();    // 如果是父订单，取自身ID

        int updatedCount=0;
        // 当订单状态为待付款时，订单状态改为已取消
        if (currentOrder.getOrderStatus().equals("0") || currentOrder.getOrderStatus().equals("1")){
            // 更新父订单状态
             updatedCount = ordersMapper.updateOrderStatus(targetParentOrderId, 4);

            // 更新该父订单下的所有子订单状态
            updatedCount += ordersMapper.updateOrderStatusByParentOrder(targetParentOrderId, "4");

            // 订单状态待接单，需要退款
            if (currentOrder.getOrderStatus().equals("1")){
                topUpService.orderRefund(currentOrder);
            }
        }


        return updatedCount;
    }



    /**
     * 新增订单
     *
     * @param orders 订单
     * @return 结果
     */
    @Override
    public int insertOrders(Orders orders) {
        // 随机生成id
        long timestamp = System.currentTimeMillis();
        orders.setOrderId(timestamp);
        orders.setCreateTime(DateUtils.getNowDate());
        return ordersMapper.insertOrders(orders);
    }

    /**
     * 修改订单
     *
     * @param orders 订单
     * @return 结果
     */
    @Override
    public int updateOrders(Orders orders) {
        orders.setUpdateTime(DateUtils.getNowDate());
        return ordersMapper.updateOrders(orders);
    }

    /**
     * 批量删除订单
     *
     * @param orderIds 需要删除的订单主键
     * @return 结果
     */
    @Override
    public int deleteOrdersByOrderIds(Long[] orderIds) {
        return ordersMapper.deleteOrdersByOrderIds(orderIds);
    }

    /**
     * 删除订单信息
     *
     * @param orderId 订单主键
     * @return 结果
     */
    @Override
    public int deleteOrdersByOrderId(Long orderId) {
        return ordersMapper.deleteOrdersByOrderId(orderId);
    }



    @Override
    @Transactional
    public int addSubOrder(OrdersBo ordersBo) {
        // 校验数据
        checkData(ordersBo);
        // 工时减少1
        ordersBo.setTime(ordersBo.getTime().subtract(BigDecimal.valueOf(1)));
        Orders orders = ordersMapper.selectOrdersByOrderId(ordersBo.getOrderId());
        if (StringUtils.isNull(orders)){
            throw new RuntimeException("未找到订单: " + ordersBo.getOrderId());
        }
        // 查询是否有子订单
        Orders orders1 = new Orders();
        orders1.setParentOrder(ordersBo.getOrderId());
        orders1.setType("0");
        List<Orders> list = ordersMapper.selectOrdersList(orders1);
        List<Orders> lists=new ArrayList<>();
        lists.add(orders);
        if (StringUtils.isNotEmpty(list)){
            lists.addAll(list);
        }
        int i = 0;
        for (Orders list1 : lists) {
            Long ordersUser = list1.getOrdersUser();
            String receivingType = list1.getReceivingType();
            // 计算费用
            BigDecimal   costs = getCostsByConfigService(ordersUser, receivingType);
            costs=costs.multiply(ordersBo.getTime()) ;
            Orders orders2 = new Orders();
            BeanUtils.copyProperties(list1,orders2 );
            orders2.setOrderId( System.currentTimeMillis());
            orders2.setOrderStatus(BusinessConstants.dict.order_status_0);
            orders2.setTotalAmount(costs);
            orders2.setParentOrder(ordersBo.getOrderId());
            orders2.setType("1");
             i+= ordersMapper.insertOrders(orders2);
        }
        return  i;
    }

    private BigDecimal  getCostsByConfigService(Long serviceTypeId, String receivingType) {

        //查询技师或车间等级
        String KEY="";
        if ("2".equals(receivingType)){
            Technician technician = technicianMapper.selectByUserId(serviceTypeId);
            if (StringUtils.isNull(technician)) {
                throw new RuntimeException("未找到技师: " + serviceTypeId);
            }

            if (StringUtils.isNull(technician.getLevel())){
                throw new RuntimeException("技师等级不能为空");
            }
            if (technician.getLevel().intValue() == 1){
                KEY="technician_level_1";
            }else if (technician.getLevel().intValue() == 2){
                KEY="technician_level_2";
            }else if (technician.getLevel().intValue() == 3){
                KEY="technician_level_3";
            }else{
                throw new RuntimeException("技师等级错误");
            }
        }
        if ("3".equals(receivingType)){
            Garage garage = garageMapper.selectByUserId(serviceTypeId);
            if (StringUtils.isNull(garage)) {
                throw new RuntimeException("未找到车间: " + serviceTypeId);
            }
            if (StringUtils.isNull(garage.getLevel())){
                throw new RuntimeException("车间等级不能为空");
            }

            if (garage.getLevel().intValue() == 1){
                KEY="workshop_level_1";
            }else if (garage.getLevel().intValue() == 2){
                KEY="workshop_level_2";
            }else{
                throw new RuntimeException("车间等级错误");
            }
        }
        SysConfig sysConfig = configMapper.checkConfigKeyUnique(KEY);
        if (StringUtils.isNull(sysConfig)){
            throw new RuntimeException("未找到配置: " + KEY);
        }
        BigDecimal bigDecimal = new BigDecimal(sysConfig.getConfigValue());
        return bigDecimal;
    }


    // 校验数据
    private void checkData(OrdersBo ordersBo) {
        // 校验数据
        if (ordersBo.getOrderId() == null) {
            throw new IllegalArgumentException("订单ID不能为空");
        }
        if (ordersBo.getTime() == null) {
            throw new IllegalArgumentException("工时不能为空");
        }
        if (ordersBo.getTime().compareTo(new BigDecimal("2")) < 0) {
            throw new IllegalArgumentException("工时不能小于2");
        }




    }
    //

    public static BigDecimal calculateFee(String rule, BigDecimal distance) {
        // 解析规则中的基础费用、包含公里数和超出的单价
        int baseFee = 0;
        int includedKms = 0;
        int extraPerKm = 0;

        Pattern pattern = Pattern.compile("基础费用(\\d+).*含(\\d+)公里.*超过每公里加(\\d+)元");
        Matcher matcher = pattern.matcher(rule);
        if (matcher.find()) {
            baseFee = Integer.parseInt(matcher.group(1));
            includedKms = Integer.parseInt(matcher.group(2));
            extraPerKm = Integer.parseInt(matcher.group(3));
        } else {
            throw new IllegalArgumentException("费用规则格式不正确");
        }

        // 校验距离合法性
        if (distance.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("距离不能为负数");
        }

        // 转换为BigDecimal以便高精度计算
        BigDecimal baseFeeBD = new BigDecimal(baseFee);
        BigDecimal includedKmsBD = new BigDecimal(includedKms);
        BigDecimal extraPerKmBD = new BigDecimal(extraPerKm);

        // 判断是否超出基础距离
        if (distance.compareTo(includedKmsBD) <= 0) {
            return baseFeeBD;
        } else {
            // 计算超出部分的距离，并向上取整到整数（不足一公里按一公里计算）
            BigDecimal extraDistance = distance.subtract(includedKmsBD)
                    .setScale(0, RoundingMode.CEILING);  // 关键修改点
            BigDecimal extraCost = extraDistance.multiply(extraPerKmBD);
            return baseFeeBD.add(extraCost);
        }
    }


    @Override
    @Transactional
    public Map<String, String> addOrderApp(OrdersBo ordersBo) {
        //同步新增用户购买订单
        //1: 判断车间和技师是否同时存在 同时存在要新增两个订单
        BigDecimal totalAmount = BigDecimal.ZERO;
        Long parentOrder=null;
        if (StringUtils.isNotNull(ordersBo.getTechnicianId())){
            Orders orders =createOrder(ordersBo,"2");
            parentOrder=orders.getOrderId();
            totalAmount=  totalAmount.add (orders.getTotalAmount());
        }
        if (StringUtils.isNotNull(ordersBo.getGarageId())){
            ordersBo.setParentOrder(parentOrder);
            Orders orders =createOrder(ordersBo,"3");
            totalAmount=  totalAmount.add (orders.getTotalAmount());
        }
        // 判断两个金额是否一致
        if (!totalAmount.equals(ordersBo.getTotalAmount())){
            throw new RuntimeException("金额不一致");
        }
        // 拉起支付
        Map<String, String> wxPayUnifiedOrderV3Result = sysTopUpService.pullUpPayment(ordersBo);
        return  wxPayUnifiedOrderV3Result;
    }

    private Orders createOrder(OrdersBo ordersBo,String type) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersBo, orders);
        if (ordersBo.getPhotosList() != null) {
            orders.setPhotos(String.join(",", ordersBo.getPhotosList()));
        }
        long timestamp = System.currentTimeMillis();
        orders.setOrderId(timestamp);
        if (type.equals("2")){
            Long technicianId = ordersBo.getTechnicianId();
            Technician technician = technicianMapper.selectTechnicianById(technicianId);
            if (StringUtils.isNull(technician)){
                throw new RuntimeException(technicianId+"技师不存在");
            }
            orders.setOrdersUser(technician.getUserId());
            orders.setTotalAmount(ordersBo.getTechnicianCost());
            ordersBo.setOrderId(orders.getOrderId());
            orders.setReceivingType("2");
        }else {
            Long garageId = ordersBo.getGarageId();
            Garage garage = garageMapper.selectGarageById(garageId);
            if (StringUtils.isNull(garage)){
                throw new RuntimeException(garageId+"车间不存在");
            }
            orders.setOrdersUser(garage.getUserId());
            orders.setTotalAmount(ordersBo.getGarageCost());
            if (StringUtils.isNull(ordersBo.getParentOrder())){
                ordersBo.setOrderId(orders.getOrderId());
            }
            orders.setReceivingType("3");

        }

        orders.setOrderStatus(BusinessConstants.dict.order_status_0);
        orders.setCreateTime(DateUtils.getNowDate());
        orders.setCreateBy(SecurityUtils.getUserId() + "");
        int i = ordersMapper.insertOrders(orders);
        if (i<=0){
            throw new RuntimeException("新增订单失败");
        }
        return orders;
    }

    @Override
    public int orderApp(OrdersBo ordersBo) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersBo, orders);


        // 分销
        if (ordersBo.getOrderStatus().equals(BusinessConstants.dict.order_status_5)) {

        }
        orders.setUpdateBy(SecurityUtils.getUserId() + "");
        orders.setUpdateTime(DateUtils.getNowDate());

        return ordersMapper.updateOrders(orders);
    }

    @Override
    public List<OrdersVo> myOrders(Orders orders) {
        Long userId = SecurityUtils.getUserId();
        SysUser user = userMapper.selectUserById(userId);
        // 判断用户角色，如果是用户，则查询用户订单，如果J技师，则查询
        orders.setOrdersUser(SecurityUtils.getUserId());
        orders.setReceivingType(user.getCurrentRole().toString());
        startPage();
        List<Orders> list = ordersMapper.selectMyOrders(orders);
        List<OrdersVo> ordersVoList = new ArrayList<>();
        for (Orders orders1 : list) {

            OrdersVo ordersVo1 = ordersToOrdersVo(orders1);
            ordersVoList.add(ordersVo1);
        }
        return ordersVoList;
    }

    @Override
    public List<OrdersVo> usersMyOrders(Orders orders) {
        orders.setUserId(SecurityUtils.getUserId());
        startPage();
        List<Orders> list = ordersMapper.selectMyOrders(orders);
        List<OrdersVo> ordersVoList = new ArrayList<>();
        for (Orders orders1 : list) {
            OrdersVo ordersVo1 = ordersToOrdersVo(orders1);
            ordersVoList.add(ordersVo1);
        }
        return ordersVoList;
    }

    private String[] splitString(String input) {
        // 如果输入字符串不为空，则按逗号分割并返回数组，否则返回null
        return input != null ? input.split(",") : null;
    }
}
